package main

import (
	"fmt"
)

type Person struct {
	Name string
	Age  int
}

// 值接收者方法（不能修改原结构体）
func (p Person) Birthday() {
	p.Age++ // 修改的是副本，原结构体不变
}

// 指针接收者方法（可以修改原结构体）
func (p *Person) SetName(name string) {
	p.Name = name // 修改原结构体
}

func increase(a, b int) int {
	return a + b
}

func DoOperation(y int, f func(int, int)) {
	f(y, 1)
}

func decrease(a, b int) {
	println("decrease result is:", a-b)
}

// 1. 传值示例 - 函数内修改不会影响外部变量
func modifyValue(num int) {
	num = 100                             // 修改的是副本
	fmt.Printf("函数内修改后的值(传值): %d\n", num) // 输出: 100
}

// 2. 传指针示例 - 函数内修改会影响外部变量
func modifyPointer(numPtr *int) {
	*numPtr = 100                              // 通过指针修改原值
	fmt.Printf("函数内修改后的值(传指针): %d\n", *numPtr) // 输出: 100
}

func main() {
	var a *int
	*a += 1
	// DoOperation(1, increase)
	DoOperation(1, decrease)

	// 这是闭包
	counter := func() func() int {
		count := 0          // 外部变量
		return func() int { // 内部函数（闭包）
			count++ // 访问外部变量
			return count
		}
	}()

	fmt.Println(counter()) // 1
	fmt.Println(counter()) // 2
	fmt.Println(counter()) // 3

	alice := Person{"Alice", 25}
	alice.Birthday()     // 值接收者，Age 不变
	alice.SetName("Bob") // 指针接收者，Name 被修改
	fmt.Println(alice)   // {Bob 25}

	//  // 原始变量
	// originalValue := 10
	// originalPointer := &originalValue  // 获取变量地址

	// fmt.Println("=== 传值演示 ===")
	// fmt.Printf("调用函数前的值: %d\n", originalValue) // 输出: 10
	// modifyValue(originalValue)  // 传递值(副本)
	// fmt.Printf("调用函数后的值: %d\n", originalValue) // 输出: 10 (未改变)

	// fmt.Println("\n=== 传指针演示 ===")
	// fmt.Printf("调用函数前的值: %d\n", *originalPointer) // 输出: 10
	// modifyPointer(originalPointer)  // 传递指针(地址副本)
	// fmt.Printf("调用函数后的值: %d\n", *originalPointer) // 输出: 100 (已改变)

	// // 3. 指针本身也是传值(复制地址)
	// fmt.Println("\n=== 指针传值演示 ===")
	// ptr := &originalValue
	// fmt.Printf("原始指针地址: %p, 指向的值: %d\n", ptr, *ptr) // 输出指针地址和值

	// // 传递指针变量(复制指针地址)
	// func(ptrCopy *int) {
	//     fmt.Printf("函数内指针地址: %p, 指向的值: %d\n", ptrCopy, *ptrCopy) // 相同地址
	//     *ptrCopy = 200  // 修改原值
	//     fmt.Printf("函数内修改后指向的值: %d\n", *ptrCopy) // 输出: 200
	// }(ptr)

	// fmt.Printf("函数外指针地址: %p, 指向的值: %d\n", ptr, *ptr) // 地址相同，值变为200 // 原始变量
	//  originalValue := 10
	//  originalPointer := &originalValue  // 获取变量地址

	//  fmt.Println("=== 传值演示 ===")
	//  fmt.Printf("调用函数前的值: %d\n", originalValue) // 输出: 10
	//  modifyValue(originalValue)  // 传递值(副本)
	//  fmt.Printf("调用函数后的值: %d\n", originalValue) // 输出: 10 (未改变)

	//  fmt.Println("\n=== 传指针演示 ===")
	//  fmt.Printf("调用函数前的值: %d\n", *originalPointer) // 输出: 10
	//  modifyPointer(originalPointer)  // 传递指针(地址副本)
	//  fmt.Printf("调用函数后的值: %d\n", *originalPointer) // 输出: 100 (已改变)

	//  // 3. 指针本身也是传值(复制地址)
	//  fmt.Println("\n=== 指针传值演示 ===")
	//  ptr := &originalValue
	//  fmt.Printf("原始指针地址: %p, 指向的值: %d\n", ptr, *ptr) // 输出指针地址和值

	//  // 传递指针变量(复制指针地址)
	//  func(ptrCopy *int) {
	// 	 fmt.Printf("函数内指针地址: %p, 指向的值: %d\n", ptrCopy, *ptrCopy) // 相同地址
	// 	 *ptrCopy = 200  // 修改原值
	// 	 fmt.Printf("函数内修改后指向的值: %d\n", *ptrCopy) // 输出: 200
	//  }(ptr)

	//  fmt.Printf("函数外指针地址: %p, 指向的值: %d\n", ptr, *ptr) // 地址相同，值变为200
}
